﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using DG.Tweening;
using System;

/// <summary>
/// UI 3d物体拖拽
/// </summary>
[RequireComponent(typeof(DragIdentify))]
public abstract class UIDrag3DBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public bool _isAutoBack = true;
    public bool _is3dObjectShowAfterBack = false;
    public float _tweenduration = 0.5f;
    public bool _isUIVisibleWhenDrag = true;       //ui开始拖拽后是否隐藏ui
    public virtual Transform _currentDragObject { get; set; }   //当前需要拖拽3d物体
    public StomachDrugSlot _slot;
    public bool _isPlayBackAudio = true;

    protected bool _isOnTweening;
    protected RectTransform _rt;
    protected DragIdentify _identyself;
    bool _isStartPostionRecorded;           //拖拽起始的位置是否被记录
    protected Vector3 _dragStartPosition;
    protected Quaternion _dragStartRotation;

    protected Vector3 _targetDragObjectPosition;
    protected Quaternion _targetDragObjectRotation;
    protected bool _onDragging;     //是否输入拖拽状态

    protected string _loopAudioName;
    bool _is_loopaudio_start;
    GameAudioSource _loopAudio;

    /// <summary>
    /// 是否允许重新记录拖拽的起始位置
    /// </summary>
    public bool IsRestartStartPostionRecord
    {
        set { this._isStartPostionRecorded = value; }
    }

    protected virtual void Awake()
    {
        _rt = GetComponent<RectTransform>();
        _identyself = GetComponentInChildren<DragIdentify>();
        InitComponet();
    }

    protected virtual void Start()
    { }

    public virtual void InitComponet() { }

    public virtual void OnBeginDrag(PointerEventData eventData)
    {
        _onDragging = true;
        //每次拖拽开始，将DragComparerManager的上次匹配的目标清空
        DragComparerManager.Instance._current_dragIdentify = null;
        //触发一次拖拽开始的事件
        HospitalEventHandler.Instance.BroadCastEvent<DragIdentify>(HospitalEventID.DRAG_BEGIN, _identyself);

        //关闭原始元素的显示
        //SetGraphicsVisble(_rt, _isUIVisibleWhenDrag);

        _currentDragObject.SetActive(true);
        DragComparerManager.Instance._currentDrag3dObject = _currentDragObject;
        _currentDragObject.position = Get3DPosition();
        ResetStartDragPosition();

    }

    //设置被拖拽物体的世界坐标位置
    public virtual Vector3 Get3DPosition()
    {
        Plane plane = new Plane(Camera.main.transform.forward * -1, Vector3.zero);
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        float dis;
        if (plane.Raycast(ray, out dis))
        {
            Vector3 point = ray.GetPoint(dis);
            return point;
        }

        return Vector3.zero;
    }

    protected virtual void Update()
    {
        if (_onDragging)
        {
            _currentDragObject.position = Vector3.Lerp(_currentDragObject.position, _targetDragObjectPosition, .5f);
            _currentDragObject.rotation = Quaternion.Lerp(_currentDragObject.rotation, _targetDragObjectRotation, .5f);
        }
    }

    public virtual void OnDrag(PointerEventData eventData)
    {
        //_currentDragObject.position = Get3DPosition();
        _targetDragObjectPosition = Get3DPosition();
        _targetDragObjectRotation = _currentDragObject.rotation;
    }

    public virtual void OnEndDrag(PointerEventData eventData)
    {
        _onDragging = false;

        //拖拽结束后，触发一个匹配事件
        HospitalEventHandler.Instance.BroadCastEvent<DragIdentify>(HospitalEventID.DRAG_MATCH, _identyself);

        if (_isAutoBack)
        {
            if(_isPlayBackAudio) HospitalUtil.PlayAudio(HospitalConsts.audio_zidonghuigui);
            _isOnTweening = true;
            _currentDragObject.DORotate(_dragStartRotation.eulerAngles, _tweenduration);
            _currentDragObject.DOMove(_dragStartPosition, _tweenduration).OnComplete(() =>
            {
                _isOnTweening = false;

                _currentDragObject.SetActive(_is3dObjectShowAfterBack);
                OnTweenBackFinished();
            });
        }
        else
        {
            _currentDragObject.SetActive(_is3dObjectShowAfterBack);
        }


    }

    public virtual void SetGraphicsVisble(Transform target, bool isshow)
    {
        Graphic[] raycastuis = target.GetComponentsInChildren<Graphic>();
        for (int i = 0; i < raycastuis.Length; i++)
            raycastuis[i].enabled = isshow;
        
        //隐藏了graphic组件后再显示时，layout的排序功能会异常，所以这里强制对layoutgroup进行排序
        if(isshow) LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent.GetComponent<RectTransform>());
    }

    public void SetToDragStartPostion()
    {
        _currentDragObject.position = _dragStartPosition;
    }

    public void ResetStartDragPosition()
    {
        if (!_isStartPostionRecorded)
        {
            _isStartPostionRecorded = true;
            _dragStartPosition = _currentDragObject.position;
            _dragStartRotation = _currentDragObject.rotation;
        }
    }

    public void SetStartDragPosition(Vector3 startDragPosition)
    {
        _dragStartPosition = startDragPosition;
    }

    protected virtual void OnTweenBackFinished()
    {

    }

    //控制一个循环音效
    public void ActiveLoopAudio(bool isEnable)
    {
        if (isEnable)
        {
            if (!_is_loopaudio_start)
            {
                _is_loopaudio_start = true;
                _loopAudio = HospitalUtil.PlayAudio(_loopAudioName, true);
            }
        }
        else
        {
            if (_is_loopaudio_start)
            {
                _is_loopaudio_start = false;
                if (_loopAudio != null) _loopAudio.Stop();
            }
        }

    }

    GameObject _pill;
    public GameObject GetDrugPill(eStomachDrugShape shape, eStomachDrugColor color)
    {
        int index = (int)shape * 3 + ((int)color + 1);
        //Debug.Log(index);
        string name = "304060202-" + index;

        if (_pill == null)
        {
            _pill = HospitalResManager.GetActiveObject(HospitalConsts.game_hospital_prefab_stomachache_BasePath, name);
            _pill.name = name;
            HospitalController.Instance.RegistCacheObject(_pill);
        }

        return _pill;
    }

    private void OnDisable()
    {
        ActiveLoopAudio(false);
    }

    protected virtual void OnDestroy()
    {
       
    }
}
